package com.bitoon.basketdudes.web.commons;

import com.bitoon.basketdudes.web.jpa.EquipoRanking;
import com.bitoon.basketdudes.web.datos.DatosRanking;
import com.bitoon.basketdudes.web.jpa.Ranking;
import com.bitoon.basketdudes.web.jpa.RankingPais;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.persistence.*;
import org.apache.log4j.Logger;

public class RankingCommon extends BaseCommons {

    private Logger log = Logger.getLogger(RankingCommon.class);

    public int totalPosicionesGlobal() {
        int retorno = 0;
        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // checked

            /*
             * Cálculo anterior . Modificado Alberto Piquer 28/3/2011
             */
            /*
            Query qc = em.createNamedQuery("Ranking.findAll");
            retorno = qc.getResultList().size();
             *
             */

            Query qc = em.createNativeQuery("select count(*) as cuantos from ranking where posicion > 0");
            BigInteger bigRetorno = (BigInteger)qc.getSingleResult();
            retorno = bigRetorno.intValue();

        } catch (Exception e) {
            log.error("No se pudo leer el total de posiciones de ranking global", e);
        } finally {
            //try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    public List<DatosRanking> listadoRankingGlobal(int offset, int limit) {

        //log.debug(">>>> Calculando ranking global");
        
        EntityManager em = null;
        List<DatosRanking> retorno = null;

        try {
            em = emfBasket.createEntityManager(); // checked
            Query q = em.createNamedQuery("Ranking.findAll");
            q.setFirstResult(offset);
            if (limit > 0) {
                q.setMaxResults(limit);
            }
            //log.debug("limit: " + limit);
            List<Ranking> consulta = new ArrayList<Ranking>();
            consulta = (List<Ranking>)q.getResultList();
            
            retorno = new ArrayList<DatosRanking>();
            Iterator iter = consulta.iterator();
            while (iter.hasNext()) {
                Ranking item = (Ranking)iter.next();
                DatosRanking aux = new DatosRanking();
                q = em.createNamedQuery("EquipoRanking.findById");

                //q.setParameter("idEquipo", item.getId());
                q.setParameter("idEquipo", item.getEquipo().getId());
                EquipoRanking e = (EquipoRanking)q.getSingleResult();

                aux.setEquipo(e);
                aux.setPosicionActual(item.getPosicion());
                aux.setPosicionAnterior(item.getAntPosicion());
                
                retorno.add(aux);
            }
        } catch (NoResultException e) {
            //log.debug("[listadoRankingGlobal] No se pudo encontrar un ranking");
        } catch (Exception e) {
            log.error("[listadoRankingGlobal] No se pudo leer el ranking global", e);
        } finally {
            // Comentado para probar a llenar las conexiones del pool
            //try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    public int totalPosicionesFiltrado(String donde, String cadena) {
        int retorno = 0;
        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // checked
            Query qc = null;

            if (donde.equals("equipos")) {
                qc = em.createNamedQuery("Ranking.findByNombreEquipo");
                qc.setParameter("nombreEquipo", "%" + cadena.toLowerCase() + "%");
            } else {
                qc = em.createNamedQuery("Ranking.findByNombreManager");
                qc.setParameter("nombreManager", "%" + cadena.toLowerCase() + "%");
            }

            retorno = qc.getResultList().size();
        } catch (Exception e) {
            log.error("No se pudo leer el total de posiciones de ranking filtrado", e);
        } finally {
            //try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    public List<DatosRanking> listadoRankingGlobalFiltrado(String donde, String cadena, int offset, int limit) {
        EntityManager em = null;
        List<DatosRanking> retorno = null;

        try {
            em = emfBasket.createEntityManager(); // checked
            Query q = null;

            if (donde.equals("equipos")) {
                q = em.createNamedQuery("Ranking.findByNombreEquipo");
                q.setParameter("nombreEquipo", "%" + cadena.toLowerCase() + "%");
            } else {
                q = em.createNamedQuery("Ranking.findByNombreManager");
                q.setParameter("nombreManager", "%" + cadena.toLowerCase() + "%");
            }
            q.setFirstResult(offset);
            if (limit > 0) {
                q.setMaxResults(limit);
            }
            List<Ranking> consulta = new ArrayList<Ranking>();
            consulta = (List<Ranking>)q.getResultList();

            retorno = new ArrayList<DatosRanking>();
            Iterator iter = consulta.iterator();
            while (iter.hasNext()) {
                Ranking item = (Ranking)iter.next();
                DatosRanking aux = new DatosRanking();
                q = em.createNamedQuery("EquipoRanking.findById");

                //q.setParameter("idEquipo", item.getId());
                q.setParameter("idEquipo", item.getEquipo().getId());
                EquipoRanking e = (EquipoRanking)q.getSingleResult();

                aux.setEquipo(e);
                aux.setPosicionActual(item.getPosicion());
                aux.setPosicionAnterior(item.getAntPosicion());

                retorno.add(aux);
            }
        } catch (NoResultException nre) {
            //log.debug("[listadoRankingGlobalFiltrado] No se pudo leer el ranking");
        } catch (Exception e) {
            log.error("[listadoRankingGlobalFiltrado] No se pudo leer el ranking global", e);
        } finally {
            //try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    public List<DatosRanking> listadoRankingPais(String idPais, int offset, int limit) {
        EntityManager em = null;
        List<DatosRanking> retorno = null;

        try {
            em = emfBasket.createEntityManager(); // checked
            Query q = em.createNamedQuery("RankingPais.findByPaisId");
            q.setParameter("paisId", idPais);
            q.setFirstResult(offset);
            if (limit > 0) {
                q.setMaxResults(limit);
            }
            List<RankingPais> consulta = new ArrayList<RankingPais>();
            consulta = (List<RankingPais>)q.getResultList();

            retorno = new ArrayList<DatosRanking>();
            Iterator iter = consulta.iterator();
            while (iter.hasNext()) {
                RankingPais item = (RankingPais)iter.next();
                DatosRanking aux = new DatosRanking();
                q = em.createNamedQuery("EquipoRanking.findById");
                q.setParameter("idEquipo", item.getId());
                EquipoRanking e = (EquipoRanking)q.getSingleResult();

                aux.setEquipo(e);
                aux.setPosicionActual(item.getPosicion());
                aux.setPosicionAnterior(item.getAntPosicion());

                retorno.add(aux);
            }
        } catch (NoResultException nre) {
            //log.debug("No se pudo leer el ranking del pais " + idPais);
        } catch (Exception e) {
            log.error("Error: ", e);
        } finally {
            //try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    public DatosRanking consultaRankingGlobal(int idEquipo) {
        EntityManager em = null;
        DatosRanking retorno = new DatosRanking();
        retorno.setPosicionActual(0);
        retorno.setPosicionAnterior(0);
        retorno.setTotalPosiciones(0);

        try {

            em = emfBasket.createEntityManager(); // checked

            // Primero calculamos cuantas posiciones hay

            Query q = em.createQuery("SELECT COUNT(r) FROM Ranking r");
            int total = ((Long)q.getSingleResult()).intValue();
            retorno.setTotalPosiciones(total);

            q = em.createNamedQuery("Ranking.findById");
            q.setParameter("id", idEquipo);
            Ranking ranking = (Ranking)q.getSingleResult();

            retorno.setPosicionActual(ranking.getPosicion());
            retorno.setPosicionAnterior(ranking.getAntPosicion());

        } catch (NoResultException e) {
            log.error("[consultaRankingGlobal][equipo " + idEquipo + " no encontrado en el ranking]");
        } catch (Exception e) {
            log.error("[consultaRankingGlobal]: " + e);
        } finally {
            //try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    public DatosRanking consultaRankingPais(int idEquipo, String idPais) {
        EntityManager em = null;
        DatosRanking retorno = new DatosRanking();
        retorno.setPosicionActual(0);
        retorno.setPosicionAnterior(0);
        retorno.setTotalPosiciones(0);

        try {

            em = emfBasket.createEntityManager(); // checked

            Query q = em.createNamedQuery("RankingPais.findByEquipoId");
            q.setParameter("equipoId", idEquipo);

            RankingPais ranking = (RankingPais)q.getSingleResult();

            retorno.setPosicionActual(ranking.getPosicion());
            retorno.setPosicionAnterior(ranking.getAntPosicion());

            q = em.createQuery("SELECT COUNT(r) FROM RankingPais r WHERE r.paisId = :paisId");
            q.setParameter("paisId", idPais);
            int total = ((Long)q.getSingleResult()).intValue();
            retorno.setTotalPosiciones(total);

        } catch (NoResultException e) {
            //log.debug("[consultaRankingPais][equipo " + idEquipo + " no encontrado en el ranking]");
        } catch (Exception e) {
            log.error("[consultaRankingPais]: " + e);
        } finally {
            //try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

}
